<?php
/**
 * 发送消息
 * Date: 2020/7/16
 * Author: sunlinxin
 */
namespace Frieza\Modules\Sysmsg\Controllers;

use App\Http\Controllers\Controller;
use App\Pockets\GridDataModel as pGridDataModel;
use Doraemon\model\AdmSysmsgType;
use Doraemon\model\Position\PositionRules;
use Doraemon\model\Sysmsg;
use Doraemon\service\position\AdmOperationModule;
use Doraemon\service\position\PositionApi;
use Doraemon\tools\Log;
use Doraemon\model\BatchSend as mBatchSend;
use Doraemon\service\BatchSend as sBatchSend;
use Doraemon\cache\BatchSend\TimeTaskData;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Form;
use Encore\Admin\Widgets\Tab;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;

class BatchSendController extends Controller
{
    public function __construct()
    {
        parent::__construct();
        Admin::script($this->addScript());
    }

    public function list(Request $request,Content $content)
    {
        $params = $request->input();
        $pageSize = $request->input("per_page", 20);
        $page = $request->input("page", 1);

        $search = [];
        if (isset($params['admin_name']) && $params['admin_name']) {
            $adminIds = [];
            $adminData = Admin::user()->where('name', 'like', '%'.$params['admin_name'].'%')->get();
            foreach ($adminData as $val) {
                $adminIds[] = $val->id;
            }
            $search['admin_id'] = $adminIds;
        }
        if (isset($params['status']) && intval($params['status']) < count(mBatchSend::STATUS_DESC)) {
            $search['status'] = intval($params['status']);
        }

        if (isset($params['type']) && in_array(intval($params['type']),[mBatchSend::NOTICE_TYPE_ACTIVITY,mBatchSend::NOTICE_TYPE_SYSTEM])) {
            $search['type'] = intval($params['type']);
        }

        if (!empty($params['time']['start']) && !empty($params['time']['end'])){
            $search['fixedtime[<>]'] = [strtotime($params['time']['start']), strtotime($params['time']['end'])];
        }
        $list = mBatchSend::getMsgPageList($page, $pageSize, $search);
        foreach ( $list['list'] as &$item ) {
            $item['msg_code'] = $item['id'] + 20000000;
            if (empty($item['fixedtime'])) {
                $item['time'] = date("Y-m-d H:i:s", $item['addtime']);
            } else {
                $item['time'] = date("Y-m-d H:i:s", $item['fixedtime']);
            }
        }
        unset($item);

        $msgCodes = array_column($list['list'],'msg_code');

        $numberSuccess = Sysmsg::getNumberByMsgCode($msgCodes);
        if(!empty($numberSuccess)){
            foreach($list['list'] as &$item){
                $item['numberSuccesses'] = $numberSuccess[$item['msg_code']];
            }
        }

        $dataList = $list['list'] ?? [];
        $ids = array_column($dataList, 'id');
        $rules = PositionApi::activeRules($ids, PositionRules::MODULE_TYPE_BATCH_SEND);
        $list['list'] = array_map(function ($v) use ($rules) {
            $v['userprofile'] = $rules[$v['id']] ?? [];
            return $v;
        }, $dataList);

        $gridModel = new pGridDataModel($list['list'], $list['total'], [
            'perPage' => $pageSize
        ]);
        $gridList = Admin::grid($gridModel,
            function (Grid $grid) use ($gridModel) {
                $grid->paginate($gridModel->getPerPage());
                $grid->disableExport();
                $grid->disableRowSelector();
                $grid->disableCreateButton();

                $grid->filter(function($filter){
                    // 去掉默认的id过滤器
                    $filter->disableIdFilter();
                    $filter->like('admin_name', '操作人员名称');
                    $status_desc = mBatchSend::STATUS_DESC;
                    $status_desc[] = '全部';
                    $filter->equal('status', '发送状态')->radio($status_desc)->default((string)count(mBatchSend::STATUS_DESC));
                    $filter->equal('type', '发送类型')->radio(mBatchSend::NOTICE_TYPE_TEXT)->default(mBatchSend::NOTICE_TYPE_ACTIVITY);
                    $filter->between('time', '发送时间')->datetime();
                });

                $grid->column("id", 'ID');
                $grid->column("msg_code", 'msgCode');
                $grid->column("admin_id", '操作人员')->display(function () {
                    return "<span style='width:80px;display: inline-block;'>".Admin::user()->find($this->admin_id)->name."</span>";
                });
                $grid->column("time", '发送时间');
                $grid->column("title", '发送标题')->display(function ($title) {
                    return "<span style='width:300px;display: inline-block;'>$title</span>";
                });
                $grid->column("message", '发送理由')->width(150);
                $grid->column("numberSuccesses", '发送数')->width(150);
                $grid->column("numberViews", '曝光数')->width(150);
                $grid->column("type", '内容类型')->using(mBatchSend::NOTICE_TYPE_TEXT)->width(90);
                $grid->column("status", '发送状态')->using(mBatchSend::STATUS_DESC)->width(90);
                $grid->column('userprofile', '用户分群')->width(200)->userProfile();
                $grid->actions(function (Grid\Displayers\Actions $actions) {
                    $actions->disableEdit();
                    $actions->disableDelete();
                    $actions->append('<a href="/admin/sysmsg/view/' . $actions->row->id . '" class="fa fa-info-circle">查看详情</a>');
                    if (in_array($actions->row->status,[
                        mBatchSend::STATUS_TYPE_TIME_SEND,
                        mBatchSend::STATUS_TYPE_ALREADY_DATA,
                        mBatchSend::STATUS_TYPE_ERR_DATA,
                        mBatchSend::STATUS_TYPE_FAILURE
                    ])) {
                        $actions->append('&nbsp;&nbsp;<a class="fa fa-trash cancel-send" data-id="' . $actions->row->id . '" href="javascript:void(0);">取消发送</a>');
                    }
                    if (in_array($actions->row->status,[
                        mBatchSend::STATUS_TYPE_ERR_DATA,
                        mBatchSend::STATUS_TYPE_FAILURE
                    ])) {
                        $actions->append('&nbsp;&nbsp;<a class="fa fa-inbox resend" data-id="' . $actions->row->id . '" href="javascript:void(0);">重新发送</a>');
                    }
                });
            });

        $tab = new Tab();
        $tab->add('任务列表', $gridList->render(), true);
        $tab->addLink('发送消息', url('admin/sysmsg/send'));
        $content->row($tab);
        return $content
            ->header('站内消息-通知')
            ->description(' ')
            ->breadcrumb(['text' => '任务列表']);
    }

    public function send(Request $request,Content $content)
    {
        $tab = new Tab();
        $form = new Form();

        $form->html("<span style='color:red;'>建议使用【用户行为-上次登录时间-指定日期范围】选择用户群，完成分群后请点击右下角按钮【查看分群人数】，如超过80万，请在提交后，联系@张志杰</span>");
        $form->html("<span style='color:red;'>如果因特殊原因发错了需要撤回，联系@张志杰</span>");
        $form->userProfile('user_profile', '用户分群')->options(\Doraemon\service\position\UserProfileModule::$other_position_rules)->generate();
        $form->divider();
        $form->fieldChange('fix', '定时发送', $form)
            ->options([0 => '否', 1 => '是'])
            ->default(1)
            ->required()
            ->callablePreCommon(function (Form $form){
            })->callableMap([
                0 => function (Form $form) {
                },
                1 => function (Form $form) {
                    $form->datetime('fixedtime', '定时时间')->default(date("Y-m-d H:i:s", strtotime("+30 minutes")))
                    ->help("发送时间至少要大于当前时间半个小时「>30分钟」");
                },
            ]);

        if (Admin::user()->can('sysmsg.send_type')){
            $noticeTypes = [1 => '系统消息（非开放资源位，仅用户管理使用）', 2 => '有奖活动'];
        }else{
            $noticeTypes = [2 => '有奖活动'];
        }

        $form->fieldChange('type', '通知类型', $form)
            ->options($noticeTypes)
            ->default(2)
            ->required()
            ->callablePreCommon(function (Form $form){
            })->callableMap([
                1 => function (Form $form) {
                    $form->select('sub_type', '通知子类型')
                        ->options(AdmSysmsgType::getSysmsgType(AdmSysmsgType::TYPE_MSG))->required();
                },
                2 => function (Form $form) {
                    $form->select('sub_type', '通知子类型')
                        ->options(AdmSysmsgType::getSysmsgType(AdmSysmsgType::TYPE_NOTICE))->required();
                },
            ]);
        $form->text('title', '发送标题')->help("发送标题/发送内容二选一必填");
        $form->textarea('content', '发送内容');
        $form->imgUpload('pic_id','上传图片');
        $form->divider();
        $form->linkSelect('link', '跳转链接');
        $form->divider();
        $form->textarea('reason', '发送原因')->rows(3);
        $form->action(url('admin/sysmsg/submitSend'));

        $tab->addLink('任务列表', url('admin/sysmsg/msgList'));
        $tab->add('发送消息', $form->render(), true);
        return $content->header('站内消息-通知')
            ->breadcrumb(
                ['text' => '发送消息'])
            ->row($tab);
    }

    public function viewInfo(Request $request, Content $content, $id = 0)
    {
        $row = mBatchSend::getByWhere(['id'=>$id]);
        if ($row['img_pic_url']) {
            $imgArr = parse_url($row['img_pic_url']);
            $row['pic_id'] = basename($imgArr['path']);
        } else {
            $row['pic_id'] = '';
        }
        $row['fix'] = $row['fixedtime'] == $row['addtime'] ? 0 : 1;
        $row['time'] = date("Y-m-d H:i:s", $row['fixedtime']);
        $userProfile = AdmOperationModule::getPositionRulesById($id, PositionRules::MODULE_TYPE_BATCH_SEND, true) ?: [];
        $row['user_profile'] = $userProfile;
        $form = new Form($row);
        $form->radio('type', '通知类型')->options([1 => '系统消息', 2 => '通知']);
        $form->select('sub_type', '通知子类型')->options(AdmSysmsgType::getSysmsgType());
        $form->display('title', '发送标题')->readonly();
        $form->radio('fix', '定时发送')->options([0 => '否', 1 => '是']);
        if ($row['fixedtime'] != $row['addtime']) {
            $form->display('time', '定时时间');
        }
        $form->display('content', '发送内容');
        $form->imgUpload('pic_id','上传图片');
        $form->display('link','发送链接');
        $form->display('message', '发送原因');
        $form->divider();
        $form->userProfile('user_profile', '用户分群')
            ->options(\Doraemon\service\position\UserProfileModule::$other_position_rules)
            ->generate();

        $form->disableReset();
        $form->disableSubmit();

        $tab = new Tab();
        $tab->add("查看详情", $form);
        return $content->header('站内消息-通知')
            ->description('任务列表')
            ->breadcrumb(
                ['text' => '任务列表', 'url' => url('admin/sysmsg/msgList')],
                ['text' => '查看详情'])
            ->row($tab);
    }

    public function submitSend(Request $request, Content $content)
    {
        try {
            $params = $request->all();
            unset($params['_token']);
            if(empty($params['title'])&& empty($params['content'])) {
                $error = new MessageBag([
                    'title' => '发送标题/发送内容二选一必填'
                ]);
                return back()->withInput()->with(compact('error'));
            }

            $result = sBatchSend::addSendRow($params);
            if ($result) {
                return redirect(url('/admin/sysmsg/msgList'))->with(compact('success'));
            } else {
                $error = new MessageBag([
                    'title' => '操作失败'
                ]);
                return back()->withInput()->with(compact('error'));
            }
        } catch (\Exception $e) {
            Log::debug($e->getMessage());
            $error = new MessageBag([
                'title' => '操作失败,信息:' . $e->getMessage()
            ]);
            return back()->with(compact('error'));
        }
    }

    /**
     * 取消任务
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function cancel(Request $request)
    {
        try {
            $id = $request->input('id', 0);
            $row = mBatchSend::getByWhere(['id'=>$id]);
            if (in_array($row['status'],[
                mBatchSend::STATUS_TYPE_TIME_SEND,
                mBatchSend::STATUS_TYPE_ALREADY_DATA,
                mBatchSend::STATUS_TYPE_ERR_DATA,
                mBatchSend::STATUS_TYPE_FAILURE
            ])) {
                $saveData = [];
                $saveData['admin_id'] = Admin::user()->id;
                $saveData['status'] = mBatchSend::STATUS_TYPE_CANCEL;
                mBatchSend::updateData($saveData, ['id'=>$id]);
                TimeTaskData::delTask($id);
            } else {
                throw new \Exception('当前发送状态不允许删除');
            }
            $result = [
                'title' => '任务 ID: ' . $id . ' 取消成功',
                'code' => 1
            ];
        } catch (\Exception $e) {
            $result = [
                'title' => '取消任务失败',
                'code' => 0,
                'msg' => $e->getMessage()
            ];
        }
        return response()->json($result);
    }

    /**
     * 重新发送
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function resend(Request $request)
    {
        try {
            $id = $request->input('id', 0);
            $row = mBatchSend::getByWhere(['id'=>$id]);
            if (in_array($row['status'],[
                mBatchSend::STATUS_TYPE_ERR_DATA,
                mBatchSend::STATUS_TYPE_FAILURE
            ])) {
                $saveData = [];
                $saveData['admin_id'] = Admin::user()->id;
                $saveData['fixedtime'] = time();
                $saveData['status'] = mBatchSend::STATUS_TYPE_TIME_SEND;
                mBatchSend::updateData($saveData, ['id'=>$id]);
            } else {
                throw new \Exception('当前任务状态不允许设置重新发送');
            }
            $result = [
                'title' => '设置成功，请耐心等待任务 ID: ' . $id . ' 开始发送',
                'code' => 1
            ];
        } catch (\Exception $e) {
            $result = [
                'title' => '设置失败',
                'code' => 0,
                'msg' => $e->getMessage()
            ];
        }
        return response()->json($result);
    }

    /**
     * js脚本
     * @return string
     */
    private function addScript()
    {
        return <<<SCRIPT
        $('.cancel-send').unbind('click').click(function(){
            var id= $(this).data('id');
            layer.confirm('确定要取消任务 '+id+' 吗？', {
                btn: ['确定', '取消']
            }, function (index) {
                layer.close(index);
                let url = '/admin/sysmsg/cancel?id=' +  id;
                let params = {};
                $.post(url, params , function (result) {
                    if (result.code == 1) {
                        layer.msg(result.title);
                    } else {
                        layer.msg(result.title + ': ' + result.msg);
                    }
                    setTimeout(function () {
                        parent.window.location.reload();
                    }, 1000);
                });
            });
        });
        $('.resend').unbind('click').click(function(){
            var id= $(this).data('id');
            layer.confirm('确定要重新发送任务 '+id+' 吗？', {
                btn: ['确定', '取消']
            }, function (index) {
                layer.close(index);
                let url = '/admin/sysmsg/resend';
                let params = {id:id};
                $.post(url, params , function (result) {
                    if (result.code == 1) {
                        layer.msg(result.title);
                    } else {
                        layer.msg(result.title + ': ' + result.msg);
                    }
                    setTimeout(function () {
                        parent.window.location.reload();
                    }, 1000);
                });
            });
        });
SCRIPT;
    }

}
